<script>
import { defineComponent, nextTick, onMounted, ref, watch } from 'vue';

import { message } from 'ant-design-vue';

import { useMapStore } from '#/store/map';

export default defineComponent({
  name: 'AMapLocationShow',
  props: {
    // 经纬度坐标 [lng, lat]
    coordinates: {
      type: Array,
      default: () => [],
    },
    // 地址名称
    addressName: {
      type: String,
      default: '',
    },
    // 详细地址
    addressDetail: {
      type: String,
      default: '',
    },
    // 是否显示地址详情
    showDetail: {
      type: Boolean,
      default: true,
    },
    // 地图宽度
    width: {
      type: String,
      default: '100%',
    },
    // 地图高度
    height: {
      type: String,
      default: '350px',
    },
    // 是否可拖拽
    draggable: {
      type: Boolean,
      default: false,
    },
    // 地图容器ID前缀，避免多个地图冲突
    mapIdPrefix: {
      type: String,
      default: 'map-show',
    },
  },
  emits: ['coordinatesChanged'],

  setup(props, { emit }) {
    // 使用地图store
    const mapStore = useMapStore();
    const map = ref(null);
    const lng = ref(121.478_94);
    const lat = ref(31.223);
    const mapContainerId = ref(`${props.mapIdPrefix}-${Date.now()}`);

    // 更新经纬度
    const updateCoordinates = () => {
      if (props.coordinates && props.coordinates.length === 2) {
        lng.value = props.coordinates[0];
        lat.value = props.coordinates[1];
      }
    };

    // 初始化地图配置
    const initMapConfig = async () => {
      try {
        if (!mapStore || typeof mapStore.getMapConfig !== 'function') {
          console.error('地图存储服务不可用');
          message.error('地图服务初始化失败');
          return false;
        }
        const config = await mapStore.getMapConfig();
        if (!config || typeof config !== 'object') {
          console.warn('未获取到有效的地图配置信息');
          return false;
        }
        // 检查必要的配置项是否存在
        if (!config.map_provider) {
          console.warn('地图配置缺少必要的服务商信息');
          // 设置默认服务商
          config.map_provider = 'amap';
        }
        return true;
      } catch (error) {
        console.error('初始化地图配置失败:', error);
        message.error('地图配置加载失败');
        return false;
      }
    };

    // 创建信息窗口内容的函数
    const createInfoContent = (lng, lat) => `
      <div style="padding: 10px;">
        ${props.addressName ? `<div style="font-weight: bold; margin-bottom: 5px;">${props.addressName}</div>` : ''}
        ${props.addressDetail ? `<div style="color: #666; margin-bottom: 5px;">${props.addressDetail}</div>` : ''}
        <div style="color: #999; font-size: 12px;">经纬度: ${lng.toFixed(6)}, ${lat.toFixed(6)}</div>
      </div>
    `;

    // 加载地图API
    const loadMapApi = () => {
      return new Promise((resolve, reject) => {
        // 检查是否已经加载了地图API
        const mapProvider = mapStore.getMapProvider();
        if (!mapProvider) {
          console.error('未找到地图服务商配置');
          message.error('地图配置错误，请检查设置');
          reject(new Error('未找到地图服务商配置'));
          return;
        }

        // 检查地图API是否已经加载
        const isApiLoaded = () => {
          switch (mapProvider) {
            case 'amap': {
              return window.AMap;
            }
            case 'baidu': {
              return window.BMap;
            }
            case 'tencent': {
              return window.TMap;
            }
            case 'tianditu': {
              return window.T;
            }
            default: {
              return false;
            }
          }
        };

        if (isApiLoaded()) {
          resolve();
          return;
        }

        // 检查是否已经有加载中的地图脚本
        const existingScript = document.querySelector(
          `script[src*="${mapProvider}"]`,
        );
        if (existingScript) {
          // 如果已经有脚本在加载中，等待它加载完成
          const checkLoaded = () => {
            if (isApiLoaded()) {
              resolve();
            } else {
              setTimeout(checkLoaded, 100);
            }
          };
          checkLoaded();
          return;
        }

        // 创建新的脚本标签
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.className = 'loadmap'; // 给script一个类名
        script.async = true; // 异步加载

        // 根据地图服务商设置脚本源
        switch (mapProvider) {
          case 'amap': {
            // 高德地图
            const amapVersion = mapStore.getAmapVersion() || '1.4.15';
            const amapKey = mapStore.getAmapKey() || '';
            const amapPlugins =
              mapStore.getAmapPlugins() ||
              'AMap.ToolBar,AMap.Geocoder,AMap.PlaceSearch';

            // 设置高德地图安全配置
            window._AMapSecurityConfig = {
              securityJsCode: mapStore.getAmapSecurityJsCode() || '',
            };

            script.src = `https://webapi.amap.com/maps?v=${amapVersion}&key=${amapKey || 'xxx'}&plugin=${amapPlugins}`;
            break;
          }
          case 'baidu': {
            // 百度地图
            const baiduMapKey = mapStore.getBaiduMapKey() || '';
            script.src = `https://api.map.baidu.com/api?v=3.0&ak=${baiduMapKey || 'xxx'}`;
            break;
          }
          case 'tencent': {
            // 腾讯地图
            const tencentMapKey = mapStore.getTencentMapKey() || '';
            script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${tencentMapKey || 'xxx'}`;
            break;
          }
          case 'tianditu': {
            // 天地图
            const tdtMapKey = mapStore.getTdtMapKey() || '';
            script.src = `https://api.tianditu.gov.cn/api?v=4.0&tk=${tdtMapKey || 'xxx'}`;
            break;
          }
          default: {
            console.error('不支持的地图服务商:', mapProvider);
            message.error('地图初始化失败：不支持的服务商');
            reject(new Error('不支持的地图服务商'));
            return;
          }
        }

        // 脚本加载完成事件
        script.addEventListener('load', () => {
          console.log('地图API加载完成');
          resolve();
        });

        // 脚本加载错误事件
        script.onerror = (error) => {
          console.error('地图API加载失败:', error);
          message.error('地图API加载失败，请检查网络连接或刷新页面重试');
          reject(error);
        };

        // 添加脚本到文档
        document.body.append(script);
      });
    };

    // 初始化地图
    const init = async () => {
      try {
        // 检查并初始化地图配置
        const configInitialized = await initMapConfig();
        if (!configInitialized) {
          return;
        }

        // 加载地图API
        await loadMapApi();

        // 根据map store中的配置获取地图服务商
        const mapProvider = mapStore.getMapProvider();
        if (!mapProvider) {
          console.error('未找到地图服务商配置');
          return;
        }

        const mapContainer = document.getElementById(mapContainerId.value);
        if (!mapContainer) {
          console.error('地图容器未找到:', mapContainerId.value);
          return;
        }

        // 创建地图实例
        switch (mapProvider) {
          case 'amap': {
            const AMap = window.AMap;
            map.value = new AMap.Map(mapContainer, {
              center: [lng.value, lat.value],
              zoom: Number.parseInt(mapStore.getDefaultZoom() || '16'),
              resizeEnable: true,
              dragEnable: props.draggable,
            });

            // 添加控件
            map.value.plugin(['AMap.ToolBar'], () => {
              map.value.addControl(new AMap.ToolBar());
            });

            // 创建标记点
            const marker = new AMap.Marker({
              position: [lng.value, lat.value],
              draggable: props.draggable,
            });
            map.value.add(marker);

            // 创建信息窗口
            const infoContent = createInfoContent(lng.value, lat.value);
            const infoWindow = new AMap.InfoWindow({
              content: infoContent,
              offset: new AMap.Pixel(0, -30),
            });
            infoWindow.open(map.value, [lng.value, lat.value]);

            // 如果支持拖拽，添加拖拽事件
            if (props.draggable) {
              // 拖拽移动中实时更新经纬度
              marker.on('dragging', () => {
                const position = marker.getPosition();
                lng.value = position.lng;
                lat.value = position.lat;
                // 更新信息窗口内容
                infoWindow.setContent(
                  createInfoContent(position.lng, position.lat),
                );
              });

              // 拖拽结束事件
              marker.on('dragend', () => {
                const position = marker.getPosition();
                lng.value = position.lng;
                lat.value = position.lat;
                emit('coordinatesChanged', [position.lng, position.lat]);
              });
            }
            break;
          }
          case 'baidu': {
            const BMap = window.BMap;
            map.value = new BMap.Map(mapContainer, {
              enableMapClick: false,
            });
            const point = new BMap.Point(lng.value, lat.value);
            map.value.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别

            // 添加控件
            const navigationControl = new BMap.NavigationControl({
              // 靠左上角位置
              anchor: window.BMAP_ANCHOR_TOP_LEFT,
              // LARGE类型
              type: window.BMAP_NAVIGATION_CONTROL_LARGE,
            });
            map.value.addControl(navigationControl);

            // 创建标记点
            const marker = new BMap.Marker(point);
            map.value.addOverlay(marker);

            // 创建信息窗口
            const infoContent = createInfoContent(lng.value, lat.value);
            const infoWindow = new BMap.InfoWindow(infoContent);
            infoWindow.open(map.value, point);

            // 如果支持拖拽，添加拖拽事件
            if (props.draggable) {
              marker.enableDragging();

              // 拖拽移动中实时更新经纬度
              marker.addEventListener('draging', (e) => {
                lng.value = e.point.lng;
                lat.value = e.point.lat;
                // 更新信息窗口内容
                const newInfoWindow = new BMap.InfoWindow(
                  createInfoContent(e.point.lng, e.point.lat),
                );
                newInfoWindow.open(map.value, e.point);
              });

              // 拖拽结束事件
              marker.addEventListener('dragend', (e) => {
                map.value.panTo(e.point);
                lng.value = e.point.lng;
                lat.value = e.point.lat;
                emit('coordinatesChanged', [e.point.lng, e.point.lat]);
              });
            }
            break;
          }
          case 'tencent': {
            // 腾讯地图实现
            const TMap = window.TMap;
            map.value = new TMap.Map(mapContainer, {
              center: new TMap.LatLng(lat.value, lng.value),
              zoom: 15,
              pitch: 0,
              rotation: 0,
              baseMap: {
                type: TMap.constants.BASEMAP_TYPE_VECTOR,
              },
            });

            // 创建标记点
            const marker = new TMap.MultiMarker({
              map: map.value,
              geometries: [
                {
                  id: '1',
                  position: new TMap.LatLng(lat.value, lng.value),
                },
              ],
            });

            // 如果支持拖拽，添加拖拽事件
            if (props.draggable) {
              marker.on('dragend', (evt) => {
                const position = evt.geometry.position;
                lng.value = position.lng;
                lat.value = position.lat;
                emit('coordinatesChanged', [position.lng, position.lat]);
              });
            }
            break;
          }
          case 'tianditu': {
            // 天地图实现
            const T = window.T;
            map.value = new T.Map(mapContainer);
            const point = new T.LngLat(lng.value, lat.value);
            map.value.centerAndZoom(point, 15);

            // 添加控件
            map.value.addControl(new T.Control.MapType());
            map.value.addControl(new T.Control.Scale());

            // 创建标记点
            const marker = new T.Marker(point);
            map.value.addOverlay(marker);

            // 创建信息窗口
            const infoContent = createInfoContent(lng.value, lat.value);
            const infoWindow = new T.InfoWindow(infoContent);
            infoWindow.open(map.value, point);

            break;
          }
          default: {
            console.error('不支持的地图服务商:', mapProvider);
            message.error('地图初始化失败：不支持的服务商');
            break;
          }
        }
      } catch (error) {
        console.error('地图初始化失败:', error);
        message.error('地图初始化失败，请刷新页面重试');
      }
    };

    // 监听坐标变化
    watch(
      () => props.coordinates,
      () => {
        updateCoordinates();
        nextTick(() => {
          if (map.value) {
            // 重新初始化地图到新的坐标位置
            init();
          }
        });
      },
      { deep: true },
    );

    // 监听地图ID前缀变化
    watch(
      () => props.mapIdPrefix,
      () => {
        mapContainerId.value = `${props.mapIdPrefix}-${Date.now()}`;
        nextTick(() => {
          init();
        });
      },
    );

    // 组件挂载时初始化
    onMounted(() => {
      updateCoordinates();
      nextTick(() => {
        init();
      });
    });

    // 返回模板需要使用的响应式数据和方法
    return {
      map,
      lng,
      lat,
      mapContainerId,
    };
  },
});
</script>
<template>
  <div class="map-show-container">
    <!-- 地图 -->
    <div class="map-wrapper">
      <div
        :id="mapContainerId"
        class="map radius-md"
        :style="{ width, height }"
      ></div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.map-show-container {
  width: 100%;
}

.map-wrapper {
  overflow: hidden;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgb(0 0 0 / 10%);
}

.map {
  width: 100%;
  height: 350px;
}

.address-info {
  padding: 16px;
  margin-top: 16px;
  background: #fafafa;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
}

:deep(.ant-descriptions-title) {
  margin-bottom: 12px;
  font-weight: 500;
  color: #262626;
}

:deep(.ant-descriptions-item-label) {
  width: 80px;
  font-weight: 500;
  color: #595959;
}

:deep(.ant-descriptions-item-content) {
  color: #262626;
}
</style>
